#ifndef __FACTORY_H__
#define __FACTORY_H__
#include "head.h"
#include "work_que.h"
#include "md5.h"

typedef struct{
    Que_t que;//队列
    pthread_cond_t cond;//条件变量
    pthread_t *pthid;//存放线程id
    short start_flag;//线程池启动标志，默认为0，启动后，设置为1
}Factory_t;



//线程池初始化
int factory_init(Factory_t *pf,int thread_num,int capacity);
//线程池启动
int factory_start(Factory_t *pf,int thread_num);
//子线程流程
void* thread_handle(void* p);
//是否是ls，cd，pwd，remove,先验证Client_State_t里边是否有token
void simple_command();
//socket,bind,listen
int tcp_init(int* socket_fd,char* ip,char* port);
//服务器端将文件发送给客户端
int download(int new_fd,train_state_t *ct);
//服务器端下载从客户端发送的文件
int upload(int new_fd);
//循环接收数据，直到接收到自己想要数量
int recv_n(int sfd,void* buf,int data_len);
//循环发送数据，直到发送到自己想要数量
int send_n(int sfd,void* buf,int data_len);
//epoll注册
int epoll_add(int epfd,int fd);
//执行cd进入对应目录
int server_cd(pcnode p,train_state_t* ct);
//执行ls得到该目录下的文件信息发送给客户端
int server_ls(pcnode p,train_state_t* ct);
//执行rm，满足客户端的请求
int server_remove(pcnode p,train_state_t* ct);
//通过getcwd拿到当前路径，并发送给客户端
int server_pwd(pcnode p,train_state_t* ct);
//TOKEN验证
int server_token(int new_fd);
//客户端输入用户名和密码进行登录
int server_login(int new_fd,train_state_t* ct,usraddr usr,char* salt,pcque pclient_que);
//客户端输入用户名和密码进行注册
int server_register(int new_fd,train_state_t* ct,usraddr usr,char* salt,pcque pclient_que);
//把path修改为上一级
void goto_prepath(char *path);
//进行一次遍历查找，创建对应的client加入队列
void enter_new_client(pcque pclientque,int new_fd,char* username,char* salt);
//遍历clientque并打印
void  show_client(pcnode head,pcnode tail);
//循环接收数据，能够显示接收数据进度
int recv_n_show(int sfd,void* buf,int data_len);
//传输文件子函数
int tran_file(int new_fd,train_state_t *ct);
//利用随机数种子产生salt
int Make_salt(char *str);
// 得到命令的key值
int cmd_type_func(char *cmd);
void error_quit(char *msg);
//从密码文件中得到salt
void get_salt(char *salt,char *passwd);
//得到md5码
int get_md5data(char *file_name,char *md5_str);
//打开数据库
int mySqlInit(MYSQL **conn,char *query);
//拿文件code
int get_file_code(char *file_name,int belongID,int precode);
//验证用户名是否匹配
int check_usr(char* usr_name,char* salt);
//验证密码是否匹配
int check_pwd(char* usr_name,char* usr_passwd);
//检查有无重名
int check_duplicates(char* usrA);
//向数据库中插入新用户的信息
int new_user_insert(char* Username,char* salt,char* UserPasswd);
//写日志
int usercmd_note(char *username,char *usercmd,char *cmdpath);
//找到code对应的precode,由返回值传出
int find_precode(int code);
//根据用户名找到ID，存入pID指向的位置
int find_ID(char *username,int *pID);
//找到文件对应的code,成功返回code,失败返回-1
int find_file_code(char *file_name,int belongID,int precode);
//循环发送该目录下文件名
int ls_func(int new_fd,int code,int belongID);
//找目标文件夹,找不到返回-1，找到返回0,并取得code,拿取md5
int find_target_file(int precode,char* filename,int belongID,char* filemd5);
//删除文件
int delete_file(int precode,char* filename,int belongID);
//被remove的文件linknum减1
void linknum_reduce(char* filemd5);
//删除文件池表项
void delete_filepool(char* filemd5);
//用户登陆记录
int userlogin_note(char *username);
//根据token找到用户名，成功返回0，失败返回-1
int get_salt_to_username(char* username,char* salt);
//检查md5码是否存在，实现秒传
int check_md5_exist(char* md5);
//向数据库中插入文件
void insert_file(int precode,char* filename,int belongID,char* md5);
//增加文件的连接数
void linknum_add(char* filemd5);
//用户队列，初始化
void clientque_init(pcque clientque);
//用户队列，增
void clientque_insert(pcque clientque,pcnode pcnew);
//用户队列，寻找当前username，若找到，返回0，该节点指针存入ptarget，没找到返回-1
int clientque_find(pcque clientque,char* username,pcnode ptarget);


#endif